package com.vhall.component.service.rbac.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.vhall.component.dao.rbac.RbacAccessMapper;
import com.vhall.component.entity.account.AccessEntity;
import com.vhall.component.entity.rbac.GroupAccessEntity;
import com.vhall.component.entity.rbac.RoleAccessEntity;
import com.vhall.component.entity.rbac.UserGroupEntity;
import com.vhall.component.entity.rbac.UserRoleEntity;
import com.vhall.component.entity.rbac.vo.AccessListReqVO;
import com.vhall.component.entity.rbac.vo.AccessUserListReqVO;
import com.vhall.component.entity.rbac.vo.AccessVO;
import com.vhall.component.framework.common.exception.BusinessException;
import com.vhall.component.plugin.common.exception.BizErrorCode;
import com.vhall.component.service.rbac.*;
import com.vhall.component.service.rbac.constant.AccessConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author dalong
 * @date 2021-05-10 17:16
 */
@Service
@Slf4j
public class RbacAccessServiceImpl implements RbacAccessService {

    @Autowired
    private RbacAccessMapper accessMapper;

    @Autowired
    private RbacUserGroupService userGroupService;

    @Autowired
    private RbacGroupAccessService groupAccessService;

    @Autowired
    private RbacUserRoleService userRoleService;

    @Autowired
    private RbacRoleAccessService roleAccessService;


    @Override
    public List<AccessVO> list(AccessListReqVO reqVO) {
        int page = reqVO.getPage();
        int pageSize = reqVO.getPageSize();
        LambdaQueryWrapper<AccessEntity> where = Wrappers.lambdaQuery();
        where.eq(AccessEntity::getStatus, AccessConstant.NORMAL_STATUS)
                .isNull(AccessEntity::getDeletedAt)
                .orderByAsc(AccessEntity::getId)
                .last("LIMIT " + (page - 1) * pageSize + "," + pageSize);

        List<AccessEntity> accessEntities = accessMapper.selectList(where);
        List<AccessVO> accessVos = new ArrayList<>();
        for (AccessEntity accessEntity : accessEntities) {
            AccessVO accessVO = new AccessVO();
            BeanUtils.copyProperties(accessEntity, accessVO);
            accessVos.add(accessVO);
        }
        return accessVos;
    }

    @Override
    public List<Integer> userAccessList(AccessUserListReqVO reqVO) {
        String accountId = reqVO.getAccountId();
        String appId = reqVO.getAppId();
        // 查询组权限列表
        List<GroupAccessEntity> groupAccessEntities = getAccessInfoByGroupId(accountId, appId);
        // 查询角色权限列表
        List<RoleAccessEntity> roleAccessEntities = getAccessInfoByRoleId(accountId, appId);
        // 数据合并处理
        List<Integer> accessIdList = new ArrayList<>();
        if (groupAccessEntities.size() == 0 && roleAccessEntities.size() == 0) {
            return accessIdList;
        } else if (groupAccessEntities.size() > 0 && roleAccessEntities.size() > 0) {
            List<Integer> groupAccessIdList = groupAccessEntities.parallelStream()
                    .map(GroupAccessEntity::getAccessId).collect(Collectors.toList());
            List<Integer> roleAccessIdList = roleAccessEntities.parallelStream()
                    .map(RoleAccessEntity::getAccessId).collect(Collectors.toList());
            groupAccessIdList.retainAll(roleAccessIdList);
            return roleAccessIdList;
        } else {
            if (groupAccessEntities.size() > 0) {
                accessIdList = groupAccessEntities.parallelStream()
                        .map(GroupAccessEntity::getAccessId).collect(Collectors.toList());
            } else {
                accessIdList = roleAccessEntities.parallelStream()
                        .map(RoleAccessEntity::getAccessId).collect(Collectors.toList());
            }
        }
        return accessIdList;
    }

    @Override
    public List<Integer> selectAllRules() {
        return accessMapper.selectAllRules();
    }

    @Override
    public Boolean add() {
        for (String key : AccessConstant.ACCESS_MAP.keySet()) {
            String val = AccessConstant.ACCESS_MAP.get(key);
            AccessEntity accessEntity = new AccessEntity();
            accessEntity.setRule(val);
            accessEntity.setTitle(key);
        }
        return true;
    }

    @Override
    public Boolean checkAccessId(List<Integer> accessIds) {
        for (Integer accessId : accessIds) {
            AccessEntity accessEntity = accessMapper.selectById(accessId);
            if (accessEntity == null) {
                throw new BusinessException(BizErrorCode.AUTH_ACCESS_EMPTY);
            }
        }
        return true;
    }

    @Override
    public AccessVO getById(Integer id) {
        AccessEntity accessEntity = accessMapper.selectById(id);
        AccessVO accessVO = new AccessVO();
        BeanUtils.copyProperties(accessEntity, accessVO);
        return accessVO;
    }

    @Override
    public List<Integer> getAccessListByRoleId(String roleName) {
        List<Integer> rules;
        List<Integer> userRemove = new ArrayList<>();
        rules = accessMapper.selectAllRules();
        if (AccessConstant.HOST.equals(roleName)) {
            return rules;
        } else if (AccessConstant.GUEST.equals(roleName)) {
            userRemove.add(AccessConstant.GUEST_REMOVE);
        } else if (AccessConstant.USER.equals(roleName)) {
            userRemove.add(AccessConstant.GUEST_REMOVE);
            userRemove.add(AccessConstant.USER_REMOVE1);
            userRemove.add(AccessConstant.USER_REMOVE2);
        } else if (AccessConstant.ASSISTANT.equals(roleName)) {
            userRemove.add(AccessConstant.ASSISTANT_REMOVE);
        } else {
            return userRemove;
        }
        if (rules != null) {
            rules.removeAll(userRemove);
        }
        return rules;
    }

    /**
     * 获取分组权限列表
     *
     * @param accountId 账号id
     * @param appId     应用id
     * @return
     */
    private List<GroupAccessEntity> getAccessInfoByGroupId(String accountId, String appId) {
        List<GroupAccessEntity> groupAccessEntities = new ArrayList<>();

        // 查询用户分组信息
        UserGroupEntity groupEntity = userGroupService.selectOne(accountId, appId, AccessConstant.NORMAL_STATUS);
        if (groupEntity != null) {
            // 获取组权限列表
            groupAccessEntities = groupAccessService.getListByGroupIdAppId(groupEntity.getGroupId(), appId);
        }
        return groupAccessEntities;
    }

    /**
     * 获取角色权限列表
     *
     * @param accountId 账号id
     * @param appId     应用id
     * @return
     */
    private List<RoleAccessEntity> getAccessInfoByRoleId(String accountId, String appId) {
        List<RoleAccessEntity> roleAccessEntities = new ArrayList<>();
        // 查询用户角色
        UserRoleEntity userRoleEntity = userRoleService.getInfo(accountId, appId, AccessConstant.NORMAL_STATUS);
        if (userRoleEntity != null) {
            // 查询角色关联的权限
            roleAccessEntities = roleAccessService.getListByRoleIdAppId(userRoleEntity.getRoleId(), appId);
        }
        return roleAccessEntities;
    }
}
